package com.cbtx.module_sp.ui.activity

import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.cbtx.module.base.SpUtils
import com.cbtx.module.base.ui.BaseFragmentPagerAdapter
import com.cbtx.module_sp.MyApplication
import com.cbtx.module_sp.R
import com.cbtx.module_sp.TaskService
import com.cbtx.module_sp.bean.PadLogRequestBean
import com.cbtx.module_sp.ui.activity.base.MyBaseVMActivity
import com.cbtx.module_sp.ui.dialog.QRCodeDialog
import com.cbtx.module_sp.ui.fragment.GoodsAuthFragment
import com.cbtx.module_sp.ui.fragment.GoodsTreasureFragment
import com.cbtx.module_sp.ui.fragment.VrFragment
import com.cbtx.module_sp.ui.vm.MainVM
import com.cbtx.module_sp.ui.window.FloatVideoWindowService
import com.txcb.lib.base.AppManager
import com.txcb.lib.base.utils.LogUtil
import com.txcb.lib.base.utils.MacUtil
import com.txcb.lib.base.utils.UIUtil
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.sp_activity_main.*
import java.util.concurrent.TimeUnit

class MainActivity : MyBaseVMActivity<MainVM>() {

    val fragmentList: MutableList<Fragment> = ArrayList()
    var renZhengFragment: GoodsAuthFragment? = null
    var goodsFragment: GoodsTreasureFragment? = null
    var vrFragment: VrFragment? = null

    var baseFragmentPagerAdapter: BaseFragmentPagerAdapter? = null

    var serviceBinder: FloatVideoWindowService.MyBinder? = null
    var mServiceBound = false

    private var reportDispose: Disposable? = null
    private var upgradeDispose: Disposable? = null

    //声明AMapLocationClient类对象
    var mLocationClient: AMapLocationClient? = null

    //声明AMapLocationClientOption对象
    var mLocationOption: AMapLocationClientOption? = null


    companion object {
        fun start(activity: Activity) {
            val intent = Intent(activity, MainActivity::class.java)
            activity.startActivity(intent)
        }

        const val DEFAULT_REPORT_POLL_TIME = 20000L

        var windowWith = 0
        var windowHeight = 0
        var mainActivity: Activity? = null
    }

    private var defaultPollReportTime = DEFAULT_REPORT_POLL_TIME
    private var defaultPollUpgradeTime = DEFAULT_REPORT_POLL_TIME * 15

    override fun getPresenterClazz(): Class<MainVM> {
        return MainVM::class.java
    }

    override fun getLayoutId(): Int {

        return R.layout.sp_activity_main
    }

    override fun initView(savedInstanceState: Bundle?) {

//        MyWebSocketUtils().init()

        mainActivity = this
        windowWith = UIUtil.getWidowsWidth(this)
        windowHeight = UIUtil.getWidowsHeight(this)

        renZhengFragment = GoodsAuthFragment()
        goodsFragment = GoodsTreasureFragment()
        vrFragment = VrFragment()

        fragmentList.add(renZhengFragment!!)
        fragmentList.add(goodsFragment!!)
        fragmentList.add(vrFragment!!)


        baseFragmentPagerAdapter = BaseFragmentPagerAdapter(supportFragmentManager, fragmentList)
        mViewPager.adapter = baseFragmentPagerAdapter


        mViewPager.currentItem = 0
        setSelect(0)

        addClickListener(mTabRenZheng)
        addClickListener(mTabGoods)
        addClickListener(mTabVr)
        addClickListener(mTabQrCode)


        mTouchView.setOnTouchListener { view, motionEvent ->
            LogUtil.d("mTouchView")
            TaskService.activityTouchTime = System.currentTimeMillis()

            checkTouch(motionEvent)
            return@setOnTouchListener false
        }

        mTouchLongView.setOnLongClickListener {
            toNetSet()
            return@setOnLongClickListener true
        }

        ivUnbind.setOnLongClickListener {
            startActivity(Intent(this@MainActivity, DeviceInfo::class.java))
            return@setOnLongClickListener true
        }

        mVM.requestWxQrCode()

        mVM.getStoreInfo()
        mVM.storeInfoEntity.observe(this, Observer {
            showMiniWidow()
        })

        initLocation()

        val serviceIntent = Intent(mActivity, TaskService::class.java)
        startService(serviceIntent)

        mVM.init()

        if (!isNetworkConnected(mActivity)) {
            showNoNet(true)
        } else {
            showNoNet(false)
        }

        reportDispose = Observable.interval(0, defaultPollReportTime, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    mVM.report()
                }

        upgradeDispose = Observable.interval(0, defaultPollUpgradeTime, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                mVM.checkVersion()
            }

        mVM.pollReportIntervalTime.observe(this, Observer {
            if (defaultPollReportTime != it.toLong()) {
                defaultPollReportTime = it.toLong()
                reportDispose?.apply {
                    if (!this.isDisposed) {
                        this.dispose()
                    }
                }
                reportDispose = Observable.interval(defaultPollReportTime, defaultPollReportTime, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe {
                        mVM.report()
                    }
            }
        })

        mVM.pollUpgradeIntervalTime.observe(this, Observer {
            if(defaultPollUpgradeTime != it.toLong()){
                defaultPollUpgradeTime = it.toLong()
                upgradeDispose?.apply {
                    if (!this.isDisposed) {
                        this.dispose()
                    }
                }
                upgradeDispose = Observable.interval(defaultPollUpgradeTime, defaultPollUpgradeTime, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe {
                        mVM.checkVersion()
                    }
            }
        })

        mVM.reportResult.observe(this, Observer {
            if (!it) {
                //获取数据后，允许进入首页
                reportDispose?.apply {
                    if (!this.isDisposed) {
                        this.dispose()
                    }
                }
                unbindService(mVideoCallServiceConnection)
                startActivity(Intent(this@MainActivity, StartActivity::class.java))
            }
        })
    }

    override fun onMyViewClick(view: View) {

        if (view.id == R.id.mTabRenZheng) {

            setSelect(0)
            mViewPager.currentItem = 0
        } else if (view.id == R.id.mTabGoods) {
            setSelect(1)
            mViewPager.currentItem = 1
        } else if (view.id == R.id.mTabVr) {
            setSelect(2)
            mViewPager.currentItem = 2
        } else if (view.id == R.id.mTabQrCode) {
            setSelect(3)

            val qRCodeDialog = QRCodeDialog(mActivity!!, mVM.mQrCodeBitmap)

            qRCodeDialog.show()
        }


    }

    override fun getData() {

    }

    override fun onBackPressed() {
        AppManager.getInstance().finishActivity(LoginActivity::class.java)
        AppManager.getInstance().finishActivity(TouFangLocationActivity::class.java)
        AppManager.getInstance().finishActivity(StartActivity::class.java)
    }

    fun setSelect(position: Int) {
        mTabRenZheng.isSelected = position == 0
        mTabGoods.isSelected = position == 1
        mTabVr.isSelected = position == 2
        mTabQrCode.isSelected = position == 3
    }

    /**
     * 悬浮菜单按钮
     */
    private val mVideoCallServiceConnection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            // 获取服务的操作对象
            serviceBinder = service as FloatVideoWindowService.MyBinder
            serviceBinder!!.service
        }

        override fun onServiceDisconnected(name: ComponentName) {}
    }


    private fun showMiniWidow() {
        val serviceVideoIntent =
            Intent(this@MainActivity, FloatVideoWindowService::class.java)
        mServiceBound = bindService(
            serviceVideoIntent,
            mVideoCallServiceConnection,
            Context.BIND_AUTO_CREATE
        ) //绑定Service
    }


    private fun initLocation() {
        //声明定位回调监听器

        if (mLocationClient != null && mLocationClient?.isStarted!!) {
            return
        }

        //初始化定位
        mLocationClient = AMapLocationClient(this.applicationContext)
        //设置定位回调监听
        //初始化AMapLocationClientOption对象
        mLocationOption = getDefaultOption()
        //设置定位参数
        mLocationClient?.setLocationOption(mLocationOption)
//        mLocationOption.setOnceLocation(true);
        // 设置定位监听
        mLocationClient?.setLocationListener(mLocationListener)
//启动定位
        mLocationClient?.startLocation()
    }

    /**
     * 默认的定位参数
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private fun getDefaultOption(): AMapLocationClientOption? {
        val mOption = AMapLocationClientOption()
        mOption.locationMode =
            AMapLocationClientOption.AMapLocationMode.Hight_Accuracy //可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.isGpsFirst = false //可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.httpTimeOut = 30000 //可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.interval = 1000 * 60 * 10.toLong() //可选，设置定位间隔。默认为2秒
        mOption.isNeedAddress = true //可选，设置是否返回逆地理地址信息。默认是true
        mOption.isOnceLocation = false //可选，设置是否单次定位。默认是false
        mOption.isOnceLocationLatest =
            false //可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP) //可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.isSensorEnable = false //可选，设置是否使用传感器。默认是false
        mOption.isWifiScan =
            true //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.isLocationCacheEnable = true //可选，设置是否使用缓存定位，默认为true
        mOption.geoLanguage =
            AMapLocationClientOption.GeoLanguage.DEFAULT //可选，设置逆地理信息的语言，默认值为默认语言（根据所在地区选择语言）
        return mOption
    }


    var lattidude = 0.0
    var longitude = 0.0

    /**
     * 定位监听
     */
    private var mLocationListener =
        AMapLocationListener { aMapLocation ->
            val padLogRequestBean = PadLogRequestBean()
            if (aMapLocation != null) {
                if (aMapLocation.errorCode == 0) {

                    //可在其中解析amapLocation获取相应内容。
                    lattidude = aMapLocation.latitude //获取纬度
                    longitude = aMapLocation.longitude //获取经度
                    val address = aMapLocation.address //地址
                    LogUtil.d("lattidude$lattidude")
                    LogUtil.d("longitude$longitude")
                    LogUtil.d("address$address")
                    val province = aMapLocation.province //省信息
                    val city = aMapLocation.city //城市信息
                    val district = aMapLocation.district //城区信息
                    val street = aMapLocation.street //街道信息
                    val streetNum = aMapLocation.streetNum //街道门牌号信息
                    val aoiName = aMapLocation.aoiName //获取当前定位点的AOI信息
                    val floor = aMapLocation.floor //获取当前室内定位的楼层
                    val address2 =
                        StringBuffer().append(province).append(city).append(district)
                            .append(street).append(streetNum).append(aoiName).toString()
                    padLogRequestBean.address = address2
                } else {
                    //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                    Log.e(
                        "AmapError", "location Error, ErrCode:"
                                + aMapLocation.errorCode + ", errInfo:"
                                + aMapLocation.errorInfo
                    )
                }
            }
            padLogRequestBean.latitude = lattidude.toString()
            padLogRequestBean.longtitude = longitude.toString()
            padLogRequestBean.deviceNo = MyApplication.mAndroidId
            mVM.requestPadLog(padLogRequestBean)
        }

    //重启app 应用
    fun reStartApp() {
        val i = baseContext.packageManager.getLaunchIntentForPackage(baseContext.packageName)
        i!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        startActivity(i)
    }
}